/**
 * Thinking in java 
 *  2018/08/01
 */
package com.dzb.nioclient;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import org.apache.tomcat.jni.Thread;

import com.kenai.jffi.Main;


/**
 * @author dzb
 * @date 2018年8月15日 下午1:39:00
 * @description  
 * @version 1.0.0
 */
public class NioClientHandle  implements Runnable{ 
	
	private String host ="127.0.0.1";
	
	private int port =8080;
	
	private Selector selector;
	
	private SocketChannel socketChannel;
	
	private volatile boolean stop;
	
	
	/**
	 * 
	 */
	public NioClientHandle( String host,int port) {
	     this.host = host ;
	     this.port =port;
	     try {
	    	 selector = Selector.open();
		     socketChannel =SocketChannel.open();
			socketChannel.configureBlocking(false);//非阻塞
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	
	@Override
	public void run() {
	     
		try {
			doConnect();
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(!stop){
			SelectionKey key = null;
			try {
				selector.select(1000);
				// 获取查询结果
				Set<SelectionKey> selected = selector.selectedKeys();
				// 遍历查询结果
				Iterator<SelectionKey> it = selected.iterator();
				
				while (it.hasNext()) {
					  key = it.next();
					  it.remove();
					  handleInput(key);
				}
			} catch (IOException e) {
				if(key==null){
					key.cancel();
					if(key.channel()==null)
						try {
							key.channel().close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
				}
				e.printStackTrace();
				System.exit(1);
			}
		}
		
		if(selector==null){
			try {
				selector.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	//链接
	public void doConnect() throws IOException{
		if(socketChannel.connect(new InetSocketAddress(host, port))){
			socketChannel.register(selector, SelectionKey.OP_READ);
		}else{
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
		}
	}
	
	//写出
	public void doWrite(SocketChannel sc) throws IOException{
		byte[] req = "你好，netty send message.....".getBytes();
		ByteBuffer  writeBuffter = ByteBuffer.allocate(req.length);
		writeBuffter.put(req);
		writeBuffter.flip();
		sc.write(writeBuffter);
		if(!writeBuffter.hasRemaining()){
			System.out.println("发送数据成功......");
		}
	}
	
	
	//执行数据
	private void handleInput(SelectionKey key){
		try {
			if(key.isValid()){
				SocketChannel sc =(SocketChannel) key.channel();
				if(key.isConnectable()){//新的链接请求
						if(sc.finishConnect())
						{
							sc.register(selector, SelectionKey.OP_READ);
							doWrite(sc);
						}else{
							System.exit(1);
						}
					
				}
				
				if(key.isReadable()){//有数据过来
					ByteBuffer readbuffer = ByteBuffer.allocate(1024);
					int readBytes;
						readBytes = sc.read(readbuffer);
						if(readBytes>0){
							readbuffer.flip();
							byte[] bytes = new byte[readbuffer.remaining()];
							readbuffer.get(bytes);
							String body = new String(bytes, "UTF-8");
							System.out.println("发送的数据"+body);
							this.stop=true;
						}else if(readBytes<0){
							key.cancel();
							sc.close();
						}
					
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	
	public static void main(String[] args) {
		new java.lang.Thread(new NioClientHandle("127.0.0.1",8080),
					"time-client").start();
	}
	
	
}
